/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Model;
import DAO.*;
import DTO.*;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import quanlysieuthi.QuanLySieuThi;

public class CModel {
    SubConfig config;
    List<CHistory> lHistory ;
    private String m_nguoi_tao;
    public CModel(String nguoi_tao){
        config = SubConfig.getInstance();
        config.init();
        this.m_nguoi_tao = nguoi_tao;
        lHistory = new ArrayList<CHistory>();        
    }
    /**
     * Hàm nàu gọi refresh tất cả các view trong csdl. Để lấy dự liệu mới nhất
     */
    public void refresh(){
        try {
            CMenuDAO dao = new CMenuDAO();
            dao.refresh("vton_kho", config);
            dao.refresh("vchitiethoadon", config);
            dao.refresh("vchitiethoadonnh", config);
            dao.refresh("vchitiethoadonxh", config);
            dao.refresh("vchitiethoadonbh", config);
            dao.refresh("vcuahang", config);
        } catch (SQLException ex) {
            Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   /**
    * Add một đối tượng history. Dùng để lưu lại lịch sử người sử dụng phần mềm
    * @param item 
    */
    public void Add(CHistory item){
        if(lHistory.contains(item)== false)
            lHistory.add(item);
    }
    /**
     * Lưu lịc sử người sử dụng phần mềm xuống csdl
     */
    public void saveHisTory(){
        CHistoryDAO hisToryDao = new CHistoryDAO();
        hisToryDao.addrows(lHistory, config);
    }  
    /**
     * Đón csdl
    
    */
    public void Close(){
        config.close();
    }
    /**
     * Lấy danh sách users
     * @return 
     */
    public List<User>getUsers(){
        UserDAO userDao = new UserDAO();
        return userDao.getAll(config);
    }
    /**
     * Tìm vị trí của user đó trong danh sách
     * @param list Truyền vào danh sách các user_group
     * @param id Truyền vào id User_group cần tìm
     * @return Trả về số dòng hiện có. Ngược lại trả về -1 không tồn tại
     */
    public int indexUserGroup(List<CUser_group> list,long id){
        int index = -1;
        for(CUser_group item : list){
            index++;
            if(item.getId() == id)
                return index;
        }
        return -1;
    }
    /**
     * Tìm vị trí tình trạng có trong danh sách
     * @param list Truyền vào danh sách
     * @param tt_id Truyền tt_id để tìm trong danh sách
     * @return Nếu tồn tại trả về vị trí của nó. Ngược lại trả về -1 không tồn tại
     */
    public int indexTinhTrang(List<CTinhTrang> list,long tt_id){
        int index = -1;
        for(CTinhTrang item : list){
            index++;
            if(item.getId() == tt_id)
                return index;
        }
        return -1;
    }
    /**
     * Hàm thực hiện chức năng tìm kiếm vị trí nv_id có trong danh sách
     * @param list Truyền vào danh sách nhân viên 
     * @param nv_id Truyền nv_id của nhân viên
     * @return Nếu tồn tại trả về vị trí . Ngược lại trả về -1 không tồn tại
     */
    public int indexNhanVien(List<CNhanVien>list,long nv_id){
        int index = -1;
        for(CNhanVien nv : list){
            index++;
            if(nv.getId() == nv_id){
                return index;
            }
        }
        return -1;
    }
    /**
     * Hàm thực hiện tìm vị trí theo kh_id có trong danh sách
     * @param list Truyền vào một danh sách các khách hàng
     * @param kh_id Truyền vào kh_id cần tìm
     * @return  Nếu tìm thấy trả về vị trí . Ngược lại trả về -1 không tồn tại
     */
    public int indexKhachHang(List<CKhachHang>list,long kh_id){
        int index = -1;
        for(CKhachHang item : list){
            index++;
            if(item.getId() == kh_id){
                return index;
            }
        }
        return -1;
    }
    /**
     * Đọc danh sách config
     * @return Trả về danh sách Config. Lấy trong bảng config
     */
    public List<CConfig> getConfig(){
        List<CConfig> list;
        CConfigDAO configDAO = new CConfigDAO();
        list = configDAO.getAll(config);                
        return list;
    }
    /**
     * Lưu danh sách các config vào trong HashMap Mỗi key của một đối tượng config sẽ tương ứng với đối tượng mà HashMap lưu trữ
     * Để truyền key sẽ lấy được đối tượng tương ứng trong Hashmap. Tránh việc dùng vòng lập for để duyệt từ đầu đến cuối mảng
     * @return Trả về một HashMap.
     */
    public HashMap setConfig(){
        HashMap parameters = new HashMap();
        List<CConfig> list = this.getConfig();
        for(CConfig item : list){
            String key = item.getName().trim();
            if(!parameters.containsKey(key)){
                parameters.put(key, item);
            }
        }
        return parameters;
    }
    
    public void insertKhachHang(int loai,String ten,String dia_chi,String dien_thoai,
            String fax,int diem_tich_luy,int nhom_kh_id,String ma_the){
        CKhachHang item = new CKhachHang();
        item.setDiaChi(dia_chi);
        item.setDienThoai(dien_thoai);
        item.setFax(fax);
        item.setHoTen(ten);
        item.setId(0);
        item.setLoai(loai);
        item.setMaThe(ma_the);
        item.setNhomKhId(nhom_kh_id);
        //return item;
        List<CKhachHang> list = new ArrayList<CKhachHang>();
        list.add(item);
        CKhachHangDAO khDao = new CKhachHangDAO();
        khDao.addrows(list, config);
        CHistory history = new CHistory();
        history.setChuc_nang("insert khach_hang");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    /**
     * Hàm thực hiện chức năng cập nhật lại thông tin của khách hàng
     * @param loai 1 là khách hàng. 2 là nhà cung cấp
     * @param ten Tên của khách hàng
     * @param dia_chi Địa chỉ khách hàng
     * @param dien_thoai Số điện thoại của khách hàng hoặc nhà cung cấp
     * @param fax Số Fax
     * @param diem_tich_luy Điểm tích lũy
     * @param nhom_kh_id Nhóm khách hàng vip ...
     * @param ma_the Số thẻ của khách hàng 
     * @param id Mã của khách hàng
     */
    public void updateKhachHang(int loai,String ten,String dia_chi,String dien_thoai,
            String fax,int diem_tich_luy,int nhom_kh_id,String ma_the,long id){
        CKhachHang item = new CKhachHang();
        item.setDiaChi(dia_chi);
        item.setDienThoai(dien_thoai);
        item.setFax(fax);
        item.setHoTen(ten);
        item.setId(0);
        item.setLoai(loai);
        item.setMaThe(ma_the);
        item.setNhomKhId(nhom_kh_id);        
        item.setId(id);
        CKhachHangDAO khDao = new CKhachHangDAO();
        khDao.updateOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("update khach_hang");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        
        this.Add(history);
    }
     /**
      * Hàm thực hiện chức năng delete kho
      * @param item Truyền vào kho cần delete
      * @return Trả về 1 delete thành công. Ngược lại không thành công
      */
    public int deleteKho(CKho item){        
        CKhoDAO khoDAO = new CKhoDAO();
        int i = khoDAO.deleteItem(item.getId(), CFields.tb_kho, config);
        CHistory history = new CHistory();
        history.setChuc_nang("delete kho");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        return i;
    }
    /**
     * Hàm thực hiện chức năng delete khách hàng
     * @param item
     * @return 
     */
    public int deleteKhachHang(CKhachHang item){
        CKhachHangDAO khDao = new CKhachHangDAO();
        //khDao.deleteOnSubmint(item, config);
        int i = khDao.deleteItem(item.getId(), CFields.tb_khach_hang, config);
        CHistory history = new CHistory();
        history.setChuc_nang("delete khach_hang");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        return i;
    }
    /**
     * Hàm thêm 1 sản phẩm
     * @param ma_san_pham
     * @param ten_san_pham
     * @param gia_nhap
     * @param ton_toi_da
     * @param ton_toi_thieu
     * @param don_gia
     * @param ton_tt_ch
     * @param ton_td_ch
     * @return 
     */
    public Boolean insertSanPham(String ma_san_pham,String ten_san_pham,double gia_nhap,int ton_toi_da,
            int ton_toi_thieu,double don_gia,int ton_tt_ch,int ton_td_ch){
        Boolean flag = false;
        try {
            CSanPham sp ;
            sp = new CSanPham();
            sp.setTenSanPham(ten_san_pham);
            sp.setGiaNhap(gia_nhap);
            sp.setSoLgTonToiDa(ton_toi_da);
            sp.setTonToiThieu(ton_toi_thieu);
            sp.setDonGia(don_gia);
            sp.setMaSanPham(ma_san_pham);
            sp.setTonToiThieuCH(ton_tt_ch);
            sp.setTonToiDaCH(ton_td_ch);
            config.setAutoCommit(false);
            CSanPhamDAO spDao = new CSanPhamDAO();
            long san_pham_id = (long)spDao.insertOnSubmit(sp, config);
            sp.setId(san_pham_id);
            List<CTon_Kho> l_tk_i =new ArrayList<CTon_Kho>();
            List<CKho> lkho = this.getAllKho();
            //Khi thêm một sản phẩm sẽ lấy danh sách kho và insert vào bảng chứa ton_kho
            // các sản phẩm tương ứng với kho
            for(CKho item : lkho){
                CTon_Kho tk = new CTon_Kho();
                tk.setKhoId(item.getId());
                tk.setSanPhamId(san_pham_id);
                tk.setTenSanPham(ten_san_pham);
                if(item.getCuaHang()){
                    tk.setTonToiDa(sp.getSoLgTonToiDa());
                    tk.setTonToiThieu(sp.getTonToiThieu());
                }
                else{
                    tk.setTonToiDa(sp.getTonToiDaCH());
                    tk.setTonToiThieu(sp.getTonToiThieuCH());
                }
                tk.setSoLuongNhap(0);
                tk.setSoLuongXuat(0);
                tk.setSoLuong(0);
                l_tk_i.add(tk);
            }
            this.insertTonKho(l_tk_i);// insert sản phẩm trong bảng tồn kho
            CHistory history = new CHistory();
            history.setChuc_nang("insert san_pham");
            history.setMota(sp.toString());
            history.setNguoiTao(this.m_nguoi_tao);
            this.Add(history);//lưu lại lịch sử khi thêm mới sản phẩm
            List<CGiaBan> lGiaBan = new ArrayList<CGiaBan>();
            CGiaBan gb = new CGiaBan();
            gb.setGiaBanKHTT(0.0);
            gb.setGiaBanKHVL(sp.getDonGia());
            gb.setGiaBanVip(0.0);
            gb.setId(1);
            gb.setGiaNhap(gia_nhap);
            gb.setSanPhamId(san_pham_id);
            gb.setNguoiTao(this.m_nguoi_tao);
            lGiaBan.add(gb);
            CGiaBanDAO gbDao = new CGiaBanDAO();
            // cập nhật giá bán của sản phẩm
            if(lGiaBan.size() > 0){
                gbDao.addrows(lGiaBan, config);
            }
            if(san_pham_id > 0){
                config.commit();// Khi thêm dữ liệu thành công thi commit
                flag = true;
            }
            else{
                config.rollback();// có vấn đề xảy ra lại cần rollback lại giá trị ban đầu
            }
        } catch (SQLException ex) {
            flag = false;
            try {
                config.rollback();
            } catch (SQLException ex1) {
                Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex1);
            }
            Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try {
                config.setAutoCommit(true);
            } catch (SQLException ex) {
                Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return flag;
    }
    /**
     * Hàm chỉnh sửa lại thông tin sản phẩm đã nhập sai
     * @param masp
     * @param ten_san_pham
     * @param gia_nhap
     * @param ton_toi_da
     * @param ton_toi_thieu
     * @param don_gia
     * @param ton_tt_ch
     * @param ton_td_ch
     * @param id
     * @return 
     */
   public Boolean updateSanPham(String masp,String ten_san_pham,double gia_nhap,int ton_toi_da,
            int ton_toi_thieu,double don_gia,int ton_tt_ch,int ton_td_ch,long id){
         CSanPham sp ;       
        sp = new CSanPham();
        sp.setTenSanPham(ten_san_pham);
        sp.setGiaNhap(gia_nhap);
        sp.setSoLgTonToiDa(ton_toi_da);
        sp.setTonToiThieu(ton_toi_thieu);
        sp.setDonGia(don_gia);
        sp.setMaSanPham(masp);
        sp.setTonToiThieuCH(ton_tt_ch);
        sp.setTonToiDaCH(ton_td_ch);
        sp.setNguoiSua(this.m_nguoi_tao);     
        sp.setId(id);
        CSanPhamDAO spDao = new CSanPhamDAO();
        spDao.updateOnSubmint(sp, config);
        CHistory history = new CHistory();
        history.setChuc_nang("update san_pham");
        
        history.setMota(sp.json());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        return true;
    }
    /**
     * Hàm thực hiện chức năng xóa sản phẩm ra khỏi danh sách. Nhưng không xóa trong database
     * @param item
     * @return 
     */
    public int deleteSanPham(CSanPham item){
        CSanPhamDAO spDao = new CSanPhamDAO();
        int t =spDao.deleteItem(item.getId(),CFields.tb_san_pham, config);
        CHistory history = new CHistory();
        history.setChuc_nang("delete san_pham");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        return t;
    }
    /**
     * Lấy danh sách các sản phẩm
     * @return 
     */
    public List<CSanPham> getSanPham(){
        CSanPhamDAO spDao = new CSanPhamDAO();
        return spDao.getAll(config);
    }
    /**
     * Hàm thực hiện chức năng thêm mới tài khoản
     * @param user_name Tên tài khoản
     * @param pass_word mật khẩu
     * @param group_id Nhóm người dùng
     * @param active 
     * @return Trả về id vừa thêm được
     */
    public long insertUser(String user_name,String pass_word,int group_id,Boolean active){
        User item = new User();
        item.setActive(active);
        item.setGroupUser(group_id);
        item.setPassword(pass_word);
        item.setUserName(user_name);
        UserDAO userDao = new UserDAO();
        long userId =(long) userDao.insertOnSubmit(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("insert users");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        return userId;
    }
    
    public Boolean updateUser(String user_name,String pass_word,int group_id,Boolean active,long id){
        User item = new User();
        item.setActive(active);
        item.setGroupUser(group_id);
        item.setPassword(pass_word);
        item.setUserName(user_name);
        item.setId(id);
        UserDAO userDao = new UserDAO();
        int t = (int)userDao.updateOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("update users");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        if(t >= 1)
            return true;
        return false;
    }
    
    public CNhanVien getNhanVienItem(long userId){
        CNhanVien item = null;
        CNhanVienDAO nvdao = new CNhanVienDAO();
        String mysql = String.format("select * from nhan_vien where user_id=%s" , userId );
        List<CNhanVien>lnv = nvdao.getAll(mysql, config);
        if(lnv.size() > 0){
            item = lnv.get(0);
        }
        return item;
    }
    
    public void deleteNhanvien(CNhanVien item){
        CNhanVienDAO nvdao = new CNhanVienDAO();
        nvdao.deleteItem(item.getId(), CFields.tb_nhan_vien, config);
        CHistory history = new CHistory();
        history.setChuc_nang("delete users");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    public void deleteUser(User item ){
        UserDAO userDao = new UserDAO();
       // userDao.deleteOnSubmint(item, config);
        userDao.deleteItem(item.getId(), CFields.tb_user, config);       
        CNhanVien nv = this.getNhanVienItem(item.getId());
        if(nv!= null){
            this.deleteNhanvien(nv);
        }
        CHistory history = new CHistory();
        history.setChuc_nang("delete user");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }        
    /// nhan vien
    
    public void insertNhanVien(long user_id,String ho_ten,String dia_chi,
            String dien_thoai,int chuc_vu,Boolean gioi_tinh,String ma_nhan_vien,Date ns){
        CNhanVien nv = new CNhanVien();
        nv.setChuc_VuId((int)chuc_vu);
        nv.setDiaChi(dia_chi);
        nv.setDienThoai(dien_thoai);
        nv.setGioiTinh(gioi_tinh);
        nv.setHoTen(ho_ten);
        nv.setMaNhanVien(ma_nhan_vien);
        nv.setNgaySinh(ns);
        nv.setUserId(user_id);        
        CHistory history = new CHistory();
        history.setChuc_nang("insert nhan_vien");
        history.setMota(nv.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        CNhanVienDAO nvDAO = new CNhanVienDAO();
        nvDAO.insertOnSubmit(nv, config);
    }
    
    public void updateNhanVien(long user_id,String ho_ten,String dia_chi,
            String dien_thoai,int chuc_vu,Boolean gioi_tinh,String ma_nhan_vien,Date ns,long id){
        CNhanVien nv = new CNhanVien();
        nv.setChuc_VuId((int)chuc_vu);
        nv.setDiaChi(dia_chi);
        nv.setDienThoai(dien_thoai);
        nv.setGioiTinh(gioi_tinh);
        nv.setHoTen(ho_ten);
        nv.setMaNhanVien(ma_nhan_vien);
        nv.setNgaySinh(ns);
        nv.setUserId(user_id);        
        nv.setId(id);
        CHistory history = new CHistory();
        history.setChuc_nang("update nhan_vien");
        history.setMota(nv.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        CNhanVienDAO nvDAO = new CNhanVienDAO();        
        nvDAO.updateOnSubmint(nv, config);
    }
    
    public List<CNhanVien> getNhanVien(){
        CNhanVienDAO nvDAO = new CNhanVienDAO();
        return nvDAO.getAll(config);
    }
    //////
    
    
    
    public CTon_Kho insertTonKho(CTon_Kho item){
        CTonKhoDAO tkDAO = new CTonKhoDAO();
        Object result = tkDAO.insertOnSubmit(item, config);
        long id = (long)result;
        item.setId(id);
        
        return item;
    }
    
    public void updateTonKho(List<CTon_Kho> tonkhos){        
        CTonKhoDAO ton_khoDAO = new CTonKhoDAO();
        ton_khoDAO.updates(tonkhos, config);
    }
    
    public void insertTonKho(List<CTon_Kho> tonkhos){
        CTonKhoDAO ton_khoDAO = new CTonKhoDAO();
        //ton_khoDAO.updates(tonkhos, config);
        ton_khoDAO.addrows(tonkhos, config);
    }
    
    public Boolean UpdateHoaDon(CHoaDon hoadon,List<CChiTietHoaDon>list){
        try {
            CHoaDonDAO hoadonDAO = new CHoaDonDAO();
            config.setAutoCommit(false);
            int i =(int) hoadonDAO.updateOnSubmint(hoadon, config);
            /*
            for(CChiTietHoaDon chitiethd : list){
                chitiethd.setHoaDonId(hoa_don_id);
            }*/
           // CChiTietHoaDonDAO cthdDAO = new CChiTietHoaDonDAO();
           // int n = cthdDAO.addrows(list, config);
            //  this.updateTonKho(list, kho_id, flag);
            CHistory history = new CHistory();
            history.setChuc_nang("update hoa_don");
            history.setMota(hoadon.toString() );
            history.setNguoiTao(this.m_nguoi_tao);
            this.Add(history);
            if(i > 0){
                return true;
            }
            /*
            if(n == list.size()){
                config.commit();
            }
            else{
                config.rollback();
            }*/
        } catch (SQLException ex) {
            Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try {
               // config.rollback();
                config.setAutoCommit(true);
            } catch (SQLException ex) {
                Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return false;
    }
      
    public Boolean deleteHoaDon(CHoaDon hoadon){
        CHoaDonDAO hdDAO = new CHoaDonDAO();
        int t = hdDAO.deleteItem(hoadon.getId(),CFields.tb_hoa_don, config);
        if(t == 0)
            return false;
        return true;
    }
    
    public Boolean InsertHoaDon(CHoaDon hoadon,List<CChiTietHoaDon>list,List<CTon_Kho> l_i,List<CTon_Kho> l_u){
        try {
            CHoaDonDAO hoadonDAO = new CHoaDonDAO();
            config.setAutoCommit(false);
            long hoa_don_id =(long)hoadonDAO.insertOnSubmit(hoadon, config);
            hoadon.setId(hoa_don_id);
            CHistory history = new CHistory();
            history.setChuc_nang("insert hoa_don");
            history.setMota(hoadon.toString() );
            history.setNguoiTao(this.m_nguoi_tao);
            this.Add(history);
            for(CChiTietHoaDon chitiethd : list){
                chitiethd.setHoaDonId(hoa_don_id);
                history = new CHistory();
                history.setChuc_nang("insert chi_tiet_hoa_don");
                history.setMota(hoadon.toString() );
                history.setNguoiTao(this.m_nguoi_tao);
                this.Add(history);
            }            
            CChiTietHoaDonDAO cthdDAO = new CChiTietHoaDonDAO();
            int n = cthdDAO.addrows(list, config);  
            if(l_i != null)
                this.insertTonKho(l_i);
            this.updateTonKho(l_u);
            if(n == list.size()){
                config.commit();
                
            }
            else{
                config.rollback();
                return false;
            }
        } catch (SQLException ex) {
            Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        finally{
            try {
                config.rollback();
                config.setAutoCommit(true);
            } catch (SQLException ex) {
                Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return true;
    }
    
    public void updateDiem(int diem,long kh_id){
        CKhachHangDAO khDAO = new CKhachHangDAO();
        khDAO.updateDiem(diem, kh_id, config);
    }
    public Boolean InsertXuatHang(CHoaDon hoadon,List<CChiTietHoaDon>list,List<CTon_Kho> l_i,List<CTon_Kho> l_u){
        try {
            CHoaDonDAO hoadonDAO = new CHoaDonDAO();
            config.setAutoCommit(false);
            long hoa_don_id =(long)hoadonDAO.insertOnSubmit(hoadon, config);
            hoadon.setId(hoa_don_id);
            CHistory history = new CHistory();
            history.setChuc_nang("insert hoa_don");
            history.setMota(hoadon.toString() );
            history.setNguoiTao(this.m_nguoi_tao);
            this.Add(history);
            for(CChiTietHoaDon chitiethd : list){
                chitiethd.setHoaDonId(hoa_don_id);
                history = new CHistory();
                history.setChuc_nang("insert chi_tiet_hoa_don");
                history.setMota(hoadon.toString() );
                history.setNguoiTao(this.m_nguoi_tao);
                this.Add(history);
            }            
            CChiTietHoaDonDAO cthdDAO = new CChiTietHoaDonDAO();
            int n = cthdDAO.addrows(list, config);            
            this.updateTonKho(l_i);
            this.updateTonKho(l_u);
            if(n == list.size()){
                config.commit();
                return true;
            }
            else{
                config.rollback();
            }
        } catch (SQLException ex) {
            Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try {
                config.rollback();
                config.setAutoCommit(true);
            } catch (SQLException ex) {
                Logger.getLogger(CModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return false;
    }
    
    public List<CChiTietHoaDon>getChiTiet(long id){
        CChiTietHoaDonDAO cthdDAO = new CChiTietHoaDonDAO();
        return cthdDAO.getChiTietHoaDon(id, config);
    }
    
    public List<CTon_Kho> getTonKho(long kho_id){
        CTonKhoDAO ton_khoDAO = new CTonKhoDAO();
        if(kho_id == -1){
            return ton_khoDAO.getAll(config);
        }
        ton_khoDAO.sWhere = String.format(" where kho_id=%s", kho_id);
        return ton_khoDAO.getAll(config);
    }
    
    public List<CTon_Kho> getTonKho(long kho_id,int thang,int nam){
        CTonKhoDAO ton_khoDAO = new CTonKhoDAO();
        if(kho_id == -1){
            ton_khoDAO.sWhere = String.format(" where thang =%s and nam =%s", kho_id,thang,nam);
            return ton_khoDAO.getAll(config);
        }
        ton_khoDAO.sWhere = String.format(" where kho_id=%s and thang =%s and nam =%s", kho_id,thang,nam);
        return ton_khoDAO.getAll(config);
    }
    
    public void insertKho(Boolean cua_hang,String ten_kho,String dia_chi,String dien_thoai,String fax){
        CKho item = new CKho();
        item.setTenKho(ten_kho);        
        item.setDiaChi(dia_chi);
        item.setCuaHang(cua_hang);
        item.setDienThoai(dien_thoai);
        item.setFax(fax);
        CKhoDAO khoDao = new CKhoDAO();
        long kho_id =(long)khoDao.insertOnSubmit(item, config);
        List<CSanPham> lsanpham = this.getSanPham();
        List<CTon_Kho> ltonkho = new ArrayList<CTon_Kho>();
        for(CSanPham sp : lsanpham){
            CTon_Kho tkho = new CTon_Kho();
            tkho.setKhoId(kho_id);
            tkho.setSanPhamId(sp.getId());
            tkho.setSoLuong(0);
            tkho.setSoLuongNhap(0);
            tkho.setSoLuongXuat(0);
            tkho.setTenSanPham(sp.getTenSanPham());
            if(item.getCuaHang()){
                tkho.setTonToiDa(sp.getTonToiDaCH());
                tkho.setTonToiThieu(sp.getTonToiThieuCH());
            }
            else{
                tkho.setTonToiDa(sp.getSoLgTonToiDa());
                tkho.setTonToiThieu(sp.getTonToiThieu());
            }
            ltonkho.add(tkho);
        }
        this.insertTonKho(ltonkho);
        CHistory history = new CHistory();
        history.setChuc_nang("insert kho");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    
    public int indexKho(List<CKho> list,long id){
        int index = -1;
        for(CKho item : list){
            index++;
            if(item.getId() == id){
                return index;
            }
        }
        return -1;
    }    
    public void updateKho(Boolean cua_hang,String ten_kho,String dia_chi,String dien_thoai,String fax,long id){
        CKho item = new CKho();
        item.setTenKho(ten_kho);        
        item.setDiaChi(dia_chi);
        item.setCuaHang(cua_hang);
        item.setDienThoai(dien_thoai);
        item.setFax(fax);
        item.setId(id);
        CKhoDAO khoDao = new CKhoDAO();
        khoDao.updateOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("update kho");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    
    public List<CKho> getAllKho(){
        CKhoDAO dao = new CKhoDAO();
        List<CKho> list = dao.getAll(config);
        return list;
    }
    
    public List<CKho>getKho(Boolean b){
        CKhoDAO dao = new CKhoDAO();
        dao.sWhere = String.format(" where %s=%s", CFields.cua_hang,b);
        List<CKho> list = dao.getAll(config);
        return list;
    }
    public List<CTinhTrang> getTinhTrang(){
        CTinhTrangDAO trangDAO = new CTinhTrangDAO();
        return trangDAO.getAll(config);
    }
    
    public void insertKhuyenMai(List<CKhuyen_mai> list){
        CKhuyenMaiDAO kmDao = new CKhuyenMaiDAO();
        kmDao.addrows(list, config);
        CHistory history = new CHistory();
        history.setChuc_nang("insert khuyen mai");
        history.setMota("them cac chuong trinh khuyen mai");
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    
    public void insertKhuyenMai(String km,Timestamp tu_ngay,Timestamp den_ngay,Boolean ap_dung,
            String mat_hang_mua,String mat_hang_tang,Double giam_gia,Boolean kh_ap_dung,
            String mo_ta,int km_id){
        CKhuyen_mai item = new CKhuyen_mai();
        item.setApDung(ap_dung);
        item.setDenNgay(den_ngay);
        item.setGiamGia(giam_gia);
        item.setKmId(km_id);
        item.setLoaiKH_AD(kh_ap_dung);
        item.setLoaiKm(km);
        item.setMatHangMua(mat_hang_mua);
        item.setMatHangTang(mat_hang_tang);
        item.setMoTa(mo_ta);
        item.setNguoiTao(this.m_nguoi_tao);
        item.setTuNgay(tu_ngay);
        List<CKhuyen_mai>list = new ArrayList<CKhuyen_mai>();
        list.add(item);
        CKhuyenMaiDAO kmDao = new CKhuyenMaiDAO();
        kmDao.addrows(list, config);
        CHistory history = new CHistory();
        history.setChuc_nang("insert khuyen mai");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    
   
   public Boolean updateKhuyenMai(CKhuyen_mai item){
        CKhuyenMaiDAO kmDao = new CKhuyenMaiDAO();
       int t =(int)kmDao.updateOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("update khuyen mai");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
        if(t == 0)
            return false;
        return true;
    }
   
    public void deleteKhuyeMai(CKhuyen_mai item){
        CKhuyenMaiDAO kmDao = new CKhuyenMaiDAO();
        kmDao.deleteOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("delete khuyen mai");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    
    public void updateLoaiKhuyenMai(long id,boolean  active,String ht_km){
        CLoai_KhuyenMai item = new CLoai_KhuyenMai();
        item.setActive(active);
        item.setHinhThucKM(ht_km);
        item.setId(id);
        CLoai_KhuyenMaiDAO kmDao = new CLoai_KhuyenMaiDAO();
        kmDao.updateOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("update loai khuyen mai");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    
    //// ton kho
    
    public void updateTonKho(CTon_Kho item,int t){
        CTonKhoDAO tonkhoDAO = new CTonKhoDAO();
        if(t == 0){//insert
            tonkhoDAO.insertOnSubmit(item, config);
        }
        else{
            tonkhoDAO.updateOnSubmint(item, config);
        }
    }
    
    public void updateAllSanPhamKho(){
        List<CSanPham> lSanpham = this.getSanPham();
        List<CKho> lkho = this.getAllKho();
        List<CTon_Kho> ltonkho = this.getTonKho();
        List<CTon_Kho> ltonkho_i = new ArrayList<CTon_Kho>();
        List<CTon_Kho> ltonkho_u = new ArrayList<CTon_Kho>();
        CTonKhoDAO tonkhoDao = new CTonKhoDAO();
        for(CKho item:lkho){
            for(CSanPham sp : lSanpham){
                CTon_Kho ton_kho = new CTon_Kho();
                ton_kho.setKhoId(item.getId());
                ton_kho.setSanPhamId(sp.getId());
                ton_kho.setSoLuong(0);
                ton_kho.setSoLuongNhap(0);
                ton_kho.setSoLuongXuat(0);
                ton_kho.setTenSanPham(sp.getTenSanPham());
                ///////////////////////////////////// toi thieu cua kho
                ton_kho.setTonToiDa(sp.getSoLgTonToiDa());
                ton_kho.setTonToiThieu(sp.getTonToiThieu());
                //////////////////toi thieu cua cua hang
                CTon_Kho current = tonkhoDao.Find(ton_kho, ltonkho);
                if(current == null){
                    ltonkho_i.add(ton_kho);
                }
            }
        }
        tonkhoDao.addrows(ltonkho_i, config);
    }
    
    public List<CTon_Kho>getTonKho(){
        CTonKhoDAO tonkhoDAO = new CTonKhoDAO();
        tonkhoDAO.sWhere = "  where " + String.format("thang = %s and nam = %s", QuanLySieuThi.thang,QuanLySieuThi.nam);
        return tonkhoDAO.getAll(config);
    }
    
    @SuppressWarnings("empty-statement")
    public List<CTon_Kho>getTonKhos(long kho_id){
        CTonKhoDAO tonkhoDAO = new CTonKhoDAO();
        String mysql = "select * from " + CFields.tb_ton_kho + " where " + CFields.kho_id + "=?";
        Object []values = new Object[1];
        values[0] = kho_id;
        return tonkhoDAO.getAll(mysql, values, config);
    }
    
    public CTon_Kho findTonKho(long san_pham_id,long kho_id){
        CTonKhoDAO tonkhoDAO = new CTonKhoDAO();
        return tonkhoDAO.Find(null, null);
    }
    /**
     * Ham thực hiện chức năng thay đổi lại 1 phần quy định của siêu thị
     * @param item 
     */
    
    public void updateConfig(CConfig item){
        CConfigDAO cfDAO = new CConfigDAO();
        cfDAO.updateOnSubmint(item, config);
        CHistory history = new CHistory();
        history.setChuc_nang("Thay doi cau hinh");
        history.setMota(item.toString());
        history.setNguoiTao(this.m_nguoi_tao);
        this.Add(history);
    }
    /**
     * Hàm lấy thông tin phiếu tương ứng của hóa đơn. Ví dụ (PN tương ứng với phiếu nhập). (PX tương ứng với phiếu xuất)
     * @param loai_phieu
     * @return 
     */
    public List<CHoaDon>getHoaDon(String loai_phieu){
        CHoaDonDAO hoa_donDAO = new CHoaDonDAO();
        hoa_donDAO.sWhere = String.format(" where %s ='%s'",CFields.loai_phieu,loai_phieu );
        return hoa_donDAO.getAll(config);
    }
    /**
     * Hàm thực hiện chức năng cập nhật lại số lượng sản phẩm tương ứng
     * @param list
     * @param a 
     */
     private void updateSoluong(List<CSanPham> list,int []a){
        for(int i = 0;i < list.size();i++){
            CSanPham item = list.get(i);
            item.setSoLgTonToiDa(a[i]);
        }
    }
     /**
      * Hàm thực hiện lưu các chức năng được khuyến mãi dùng để cập nhật cho 1 hóa đơn khi tham gia mua hàng
      * @param giam_gia
      * @param mua_N_tangM
      * @param mua_N_giamM
      * @param mua_NtangMk 
      */
    public void getChuongTrinhKH(HashMap giam_gia,HashMap mua_N_tangM,HashMap mua_N_giamM,HashMap mua_NtangMk){
        Date d = new Date();
        Timestamp ngay = new Timestamp(d.getYear(), d.getMonth(), d.getDate(), 2, 3, 5, 0);
        CKhuyenMaiDAO kmDao = new CKhuyenMaiDAO();
        List<CKhuyen_mai> lkh_mai = new ArrayList<CKhuyen_mai>();
        String mysql =" select * from " + CFields.tb_khuyen_mai + " where tu_ngay <=? and den_ngay >=? ";
        Object []values ={ngay,ngay};
        lkh_mai = kmDao.getAll(mysql, values, config);
        int index1 = 0;
        int index2 = 0;
        int index3 = 0;
        int index4 = 0;
        for(CKhuyen_mai item : lkh_mai){
            int kmid = (int)item.getKmId();
            List<ChiTietKhuyenMai>list = getListSanPhamChiTiet(item.getMatHangMua(),item.getMatHangTang(),item.getGiamGia());
            switch(kmid){
                case 1:{//gia gia % theo cac mat hang
                    index1++;
                    String key = "loai1" + String.format("%d", index1);
                    giam_gia.put(key,list);
                    break;
                }
                case 2:{
                    index2++;
                    String key = "loai2" + String.format("%d", index2);
                    mua_N_tangM.put(key, list);
                    break;
                }
                case 3:{
                    index3++;
                    String key = "loai3" + String.format("%d", index3);
                    mua_N_giamM.put(key, list);
                    break;
                }
                case 4:{
                    index4++;
                    String key = "loai4" + String.format("%d", index4);
                    mua_NtangMk.put(key, list);
                    break;
                }
            }
        }
        //lkh_mai = kmDao.getAll(config);
        
    }
            
    /**
     * hàm thực hiện chức năng phân tích khuyến mãi của mặt hàng
     * @param mua_hang_id
     * @param tang_hang_id
     * @param giam_gia
     * @return 
     */
    public  List<ChiTietKhuyenMai>getListSanPhamChiTiet(String mua_hang_id,String tang_hang_id,double giam_gia){
        List<ChiTietKhuyenMai>list_chi_tiet_km = new ArrayList<ChiTietKhuyenMai>();
        List<CSanPham> mua_hang = new ArrayList<CSanPham>();
        List<CSanPham> tang_hang = new ArrayList<CSanPham>();     
        String []strMuahangid = mua_hang_id.split(",");// mỗi mặt hàng cách nhau bởi dấu ","
        String mh_id = "";
        int []a_mh = new int[strMuahangid.length];
        String m ="";
        for(int i = 0; i < strMuahangid.length;i++){
            m = strMuahangid[i];
            String []am = m.split("::");// mã mặt hàng tương ứng với số lượng ví dụ : 1 :: 2 .mã 1 với số lượng là 2
            if(!mh_id.equals("")){
                mh_id = mh_id + ",";
            }
            mh_id = mh_id + am[0];
            if(am.length >=2){
                int t = Integer.parseInt(am[1]);
                a_mh[i] = t;// mảng lưu số lượng tương ứng với mặt hàng mua
            }
        }
        String tang_id = "";
        strMuahangid = tang_hang_id.split(",");
        int []b_mh = new int[strMuahangid.length];
        m = "";
        for(int i = 0; i < strMuahangid.length;i++){
            m = strMuahangid[i];
            String []am = m.split("::");
            if(!tang_id.equals("")){
                tang_id = tang_id + ",";
            }
            tang_id = tang_id + am[0];
            if(am.length >=2){
                int t = Integer.parseInt(am[1]);
                b_mh[i] = t;// mảng lưu số lượng tương ứng với mặt hàng được tặng
            }
        }
        CSanPhamDAO spdao = new CSanPhamDAO();
        String mysql = "select * from " + CFields.tb_san_pham + " where id in(";
        mua_hang = spdao.getAll(mysql + mh_id + ")", config);// đọc danh sách các mặt hàng mua
        tang_hang = spdao.getAll(mysql + tang_id + ")", config);// đọc danh sách các mặt hàng được tặng
        this.updateSoluong(mua_hang, a_mh);
        this.updateSoluong(tang_hang, b_mh);        
        int i = 0;
        int l = 0;
        ChiTietKhuyenMai ct;
        CSanPham item ;
        if(mua_hang.size() > tang_hang.size()){
            l = tang_hang.size();
            for(i = 0; i < l;i++){
                ct = new ChiTietKhuyenMai();
                item = mua_hang.get(i);
                ct.setMhmId(item.getId());
                ct.setMaHangMua(item.getTenSanPham());
                ct.setSoLuongMua(item.getSoLgTonToiDa());
                item = tang_hang.get(i);
                ct.setMhtId(item.getId());
                ct.setMaHangTang(item.getTenSanPham());
                ct.setGiamGia(giam_gia);
                ct.setSoLuongTang(item.getSoLgTonToiDa());
                if(list_chi_tiet_km.contains(ct)== false){
                    list_chi_tiet_km.add(ct);
                }
            }
            while(i < mua_hang.size()){
                ct = new ChiTietKhuyenMai();
                item = mua_hang.get(i);
                ct.setMhmId(item.getId());
                ct.setMaHangMua(item.getTenSanPham());                
                ct.setGiamGia(giam_gia);
                ct.setSoLuongMua(item.getSoLgTonToiDa());
                if(list_chi_tiet_km.contains(ct)== false){
                    list_chi_tiet_km.add(ct);
                }
                i++;
            }
        }
        else{
            l = mua_hang.size();
            for(i = 0; i < l;i++){
                ct = new ChiTietKhuyenMai();
                item = mua_hang.get(i);
                ct.setMhmId(item.getId());
                ct.setMaHangMua(item.getTenSanPham());
                ct.setSoLuongMua(item.getSoLgTonToiDa());
                item = tang_hang.get(i);
                ct.setMhtId(item.getId());
                ct.setMaHangTang(item.getTenSanPham());
                ct.setSoLuongTang(item.getSoLgTonToiDa());
                ct.setGiamGia(giam_gia);
                if(list_chi_tiet_km.contains(ct)== false){
                    list_chi_tiet_km.add(ct);
                }
            }
            while(i < tang_hang.size()){
                ct = new ChiTietKhuyenMai();
                item = tang_hang.get(i);
                ct.setMhmId(item.getId());
                //ct.setMaHangMua(item.getTenSanPham());    
                ct.setMaHangTang(item.getTenSanPham());
                ct.setSoLuongTang(item.getSoLgTonToiDa());
                ct.setGiamGia(giam_gia);
                if(list_chi_tiet_km.contains(ct)== false){
                    list_chi_tiet_km.add(ct);
                }
                i++;
            }
        }
        return list_chi_tiet_km;
    }
    
  /**
   * Hàm thực hiện chức năng lấy giá bán của các sản phẩm
   * @return Trả về danh sách giá bán của các sản phẩm
   */
    public List<CGiaBan> getGiaBan(){
        List<CGiaBan> lGiaBan = new ArrayList<CGiaBan>();
        List<CSanPham> sanphams = new ArrayList<CSanPham>();
        CSanPhamDAO spDao = new CSanPhamDAO();
        CGiaBanDAO gbDao = new CGiaBanDAO();
        String mysql = "select sp.* from " + CFields.tb_san_pham + " sp ";
        mysql+= " where sp.id not in (select san_pham_id from " + CFields.tb_gia_ban + ")";
        sanphams = spDao.getAll(mysql, config);
        for(CSanPham item : sanphams){
            CGiaBan gb = new CGiaBan();
            gb.setGiaBanKHTT(item.getDonGia());
            gb.setGiaBanKHVL(item.getDonGia());
            gb.setGiaBanVip(item.getDonGia());
            gb.setGiaNhap(item.getGiaNhap());
            gb.setId(1);
            gb.setSanPhamId(item.getId());
            gb.setNguoiTao(this.m_nguoi_tao);
            lGiaBan.add(gb);
            CHistory history = new CHistory();
            history.setChuc_nang("update gia ban san pham");
            history.setMota(gb.toString());
            history.setNguoiTao(this.m_nguoi_tao);
            this.Add(history);
        }
        if(lGiaBan.size() > 0){
            gbDao.addrows(lGiaBan, config);
        }
        lGiaBan = gbDao.getAll(config);
        return lGiaBan;
    }                        
}
